<?php

/*
*	CLASE PARA LOS MODELOS
*/
class Model {
	
	var $table;
	var $db;
	var $page;
	var $pages = array();
	var $validate = array();
	
	function Model($cache_time=0, $cache_force=false) {
		global $database, $database_config;
		
		if(!$database) {
			$database = new DB($database_config);
			if($database->error) error_500($database->error);
		}
		
		if($cache_time) {
			$this->db = new DBCache(strtolower(get_class($this)),$cache_time * 60,$cache_force,$database);
		} else {
			$this->db =& $database;
		}
		
		$this->table();
	}
	
	function table($table='') {
		$table = $table ? $table : Inflector::pluralize(get_class($this));
		$this->table = strtolower($table);
	}
	
	function get_obj_fields() {
		$parent = get_class_vars(get_parent_class($this));
		$child = get_object_vars($this);
		
		if($parent === false) $child = false;
		else foreach($parent as $key=>$value) unset($child[$key]);
		
		return $child;
	}
	
	function query($sql) {
		return $this->db->query($sql);
	}
	
	function escape($str) {
		return $this->db->escape($str);
	}
	
	function find($id=null, $fields=null) {
		$this->id = $id ? $id : null;
		$fields = $fields ? $fields : '*';
		$sql = 'SELECT '.$fields.' FROM '.$this->table.' WHERE id = '.intval($this->id).' ';
		$this->query($sql);
		$row = $this->db->fetch_row();
		$this->id = $row['id'];
		return $row;
	}
	
	function find_by($fields=array(), $order=null, $limit=null, $type=null) {
		$field = array();
		foreach($fields as $name => $value) {
			switch ( $type ) {
				case 'LIKE':
					$field[] = $name." LIKE '%".$this->escape($value)."%'" ;
				break;
						
				default:
					$field[] = $name."='".$this->escape($value)."'" ;
				break;
			} 
		}
		$extra = 'WHERE '.join(' OR ',$field);
		return $this->find_all(null, $order, $limit, $extra);
	}
	
	function find_count($field=null, $extra=null) {
		$field = $field ? $field : '*';
		$sql = 'SELECT COUNT('.$field.') AS count FROM '. $this->table;
		if($extra) $sql.= $extra;
		$this->query($sql);
		$data = $this->db->fetch_row();
		if (isset($data['count'])) {
	        return $data['count'];
	    }
		return 0;
	}
	
	function find_all($fields=null, $order=null ,$limit=null, $extra=null) {
		$fields = $fields ? $fields : '*';
		$sql = 'SELECT '.$fields.' FROM '. $this->table.' ';
		if($extra) $sql.= $extra.' ';
		if($order) $sql.= 'ORDER BY '.$order.' ';
		$limit = $this->find_pages($limit);
		if($limit) $sql.= 'LIMIT '.$limit;
		$this->query($sql);
		return $this->db->fetch_rows();
	}
	
	function active_pages($limit= 20, $n= 1) {
		if(!is_numeric($n)) $n = 1;
		$this->page = array($limit,$n);
	}
	
	function find_pages($total) {
		if(!is_null($total) || is_array($this->page)) {
			if(!$total) {
				$sql = 'SELECT id FROM '.$this->table;
				$this->query($sql);
				$total = $this->db->last_num_rows();
			}

			$limit = $this->page[0];
			$n = $this->page[1]-1;
			$last = ceil($total/$limit);
			$index = $n * $limit;

			if(($index+$limit)>$total) {
				$n = $last-1;
				$index = $n * $limit;
			}
			
			$prev = $n;
			$now = $n+1;
			if($prev <= 0) $prev = 1;
			if($now == $last) $next = $now;
			else $next = $now+1;
			
			$this->pages['total'] = $total;
			$this->pages['now'] = $now;
			$this->pages['first'] = 1;
			$this->pages['last'] = $last;
			$this->pages['next'] = $next;
			$this->pages['prev'] = $prev;
			
			
			$pages = array();
			$min = max(1, $now-ceil(4));
			$max = min($last, $now+floor(4));
			for($i=$min; $i<=$max; $i++) {
				$pages['page'][] = $i;
			}
			
			if ($min!=1) { 
				$pages['min'] = '...';
				$pages['first'] = 1;
			}
			if ($max!=$last) { 
				$pages['max'] = '...';
				$pages['last'] = $last;
			}
			
			$this->pages['pages'] = $pages;
			
			return $index.','.$limit;
		}
		return null;
	}
	
	function get_pages() {
		$this->page = null;
		return $this->pages;
	}
	
	function save($fields=null) {
		$fields = $fields ? $fields : $this->get_obj_fields();
		if(isset($this->id)) {
			unset($fields['id']);
			return $this->save_fields($fields);
		}
		$sql = 'INSERT INTO '.$this->table;
	    $sql .= ' ('.join(', ', array_keys($fields)).')';
		foreach($fields as $field => $value) $fields[$field] = $this->escape($value);
	    $sql .= " VALUES ('".join("', '", $fields)."') ";
		echo $sql;
		$this->query($sql);
		if($this->db->last_affected()) {
			$this->id = $this->db->last_id();
			return $this->id;
		}
		return false;
	}
	
	function save_field($name, $value, $id=null) {
		if($id) $this->id = $id;
		$sql = 'UPDATE '.$this->table.' SET ';
		$sql.= $name."='".$value."' WHERE id = ".intval($this->id);
		$this->query($sql);
		return $this->db->last_affected();
	}
	
	function save_fields($fields=array(), $id=null) {
		if($id) $this->id = $id;
		$field= array();
		$sql = 'UPDATE '.$this->table.' SET ';
		foreach($fields as $name => $value) $field[] = $name."='".$this->escape($value)."'" ;
		$sql .= join(', ', $field).' WHERE id = '.intval($this->id);
		$this->query($sql);
		return $this->db->last_affected();
	}
	
	function delete($id=null) {
		$id = $id ? $id : $this->id;
		$sql = 'DELETE FROM '.$this->table.' WHERE id = '.intval($id).' LIMIT 1';
		unset($this->id);
		$this->query($sql);
		return $this->db->last_affected();
	}
	
	function clear() {
		foreach($this->get_obj_fields() as $key => $value) unset($this->$key);
		return true;
	}
	
	function get_fields() {
		return $this->db->get_fields($this->table);
	}
	
	function validates($data = array(), $return = false) {
		$bad_fields = array();
		if(count($this->validate)) {
    		foreach ($this->validate as $field => $validator) {
            	if (isset($data[$field]) && !preg_match($validator, $data[$field])) {
                	$bad_fields[$field] = $data[$field];
            	}
        	}
		}
		if($return) return $bad_fields;
		if(count($bad_fields)) return false;
		return true;
    }
	
}

class Inflector {

	function pluralize($word)
    {
		$word = strtolower($word);
        $plural = array(
        '/(quiz)$/i' => '\1zes',
        '/^(ox)$/i' => '\1en',
        '/([m|l])ouse$/i' => '\1ice',
        '/(matr|vert|ind)ix|ex$/i' => '\1ices',
        '/(x|ch|ss|sh)$/i' => '\1es',
        '/([^aeiouy]|qu)ies$/i' => '\1y',
        '/([^aeiouy]|qu)y$/i' => '\1ies',
        '/(hive)$/i' => '\1s',
        '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
        '/sis$/i' => 'ses',
        '/([ti])um$/i' => '\1a',
        '/(buffal|tomat)o$/i' => '\1oes',
        '/(bu)s$/i' => '\1ses',
        '/(alias|status)/i'=> '\1es',
        '/(octop|vir)us$/i'=> '\1i',
        '/(ax|test)is$/i'=> '\1es',
        '/s$/i'=> 's',
        '/$/'=> 's');
        
        $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');

        $irregular = array(
        'person' => 'people',
        'man' => 'men',
        'child' => 'children',
        'sex' => 'sexes',
        'move' => 'moves');

        $lowercased_word = strtolower($word);

        foreach ($uncountable as $_uncountable){
            if(substr($lowercased_word,(-1*strlen($_uncountable))) == $_uncountable){
                return $word;
            }
        }

        foreach ($irregular as $_plural=> $_singular){
            if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
                return preg_replace('/('.$_plural.')$/i', substr($arr[0],0,1).substr($_singular,1), $word);
            }
        }

        foreach ($plural as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                return preg_replace($rule, $replacement, $word);
            }
        }
        return false;

    }
}

?>